﻿using ICSharpCode.AvalonEdit;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace FinalPointSet.Model.Control
{
    /// <summary>
    /// 占位符的管理类
    /// </summary>
    public class AvalonEditTextElement
    {
        #region Fields

        /// <summary>
        /// 文本框和Visual画刷对应的字典
        /// </summary>
        private static readonly Dictionary<TextEditor, VisualBrush> TxtBrushes = [];

        #endregion Fields

        #region Attached DependencyProperty

        /// <summary>
        /// 占位符的附加依赖属性
        /// </summary>
        public static readonly DependencyProperty PlaceholderProperty = DependencyProperty.RegisterAttached(
        "Placeholder", typeof(string), typeof(AvalonEditTextElement),
        new PropertyMetadata("请在此处输入", OnPlaceholderChanged));

        /// <summary>
        /// 获取占位符
        /// </summary>
        /// <param name="obj">占位符所在的对象</param>
        /// <returns>占位符</returns>
        public static string GetPlaceholder(DependencyObject obj)
        {
            return (string)obj.GetValue(PlaceholderProperty);
        }

        /// <summary>
        /// 设置占位符
        /// </summary>
        /// <param name="obj">占位符所在的对象</param>
        /// <param name="value">占位符</param>
        public static void SetPlaceholder(DependencyObject obj, string value)
        {
            obj.SetValue(PlaceholderProperty, value);
        }

        #endregion Attached DependencyProperty

        #region Events Handling

        /// <summary>
        /// 占位符改变的响应
        /// </summary>
        /// <param name="d">来源</param>
        /// <param name="e">改变信息</param>
        public static void OnPlaceholderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //绑定加载事件, 通过加载事件来检查文本变动, 从而改变占位符显示与隐藏
            if (d is TextEditor te)
            {
                te.Loaded -= PlaceholderTextBox_Loaded;
                te.Loaded += PlaceholderTextBox_Loaded;
            }
        }

        /// <summary>
        /// 占位符文本框加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void PlaceholderTextBox_Loaded(object? sender, EventArgs e)
        {
            Debug.Print("PlaceholderTextBox_Loaded");
            if (sender is TextEditor te)
            {
                LoadPlaceHolder(te);
            }
        }

        /// <summary>
        /// 文本变化的响应
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void PlaceholderTextBox_TextChanged(object? sender, EventArgs e)
        {
            if (sender is TextEditor tb && TxtBrushes.TryGetValue(tb, out VisualBrush? value))
            {
                var placeholderVisualBrush = value;
                Debug.Print($"PlaceholderTextBox_TextChanged, TextEditor.Text={tb.Text}, IsNullOrEmpty={string.IsNullOrEmpty(tb.Text)}, VisualBrush={placeholderVisualBrush}");
                tb.Background = string.IsNullOrEmpty(tb.Text) ? placeholderVisualBrush : null;
            }
        }

        /// <summary>
        /// 文本框卸载的响应
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void PlaceholderTextBox_Unloaded(object? sender, RoutedEventArgs e)
        {
            var tb = sender as TextEditor;
            if (tb != null && TxtBrushes.ContainsKey(tb))
            {
                TxtBrushes.Remove(tb);

                tb.TextChanged -= PlaceholderTextBox_TextChanged;
                tb.Unloaded -= PlaceholderTextBox_Unloaded;
                Debug.Print("PlaceholderTextBox_Unloaded");
            }
        }

        /// <summary>
        /// 初始化占位提示
        /// </summary>
        /// <param name="txt"></param>
        private static void LoadPlaceHolder(TextEditor txt)
        {
            Debug.Print("LoadPlaceHolder()");
            if (txt != null && !TxtBrushes.ContainsKey(txt))
            {
                Debug.Print("LoadPlaceHolder(), 开始设置PlaceHolder");
                var placeholderTextBlock = new TextBox()
                {
                    Opacity = 0.8,
                    FontSize = 14,
                    TextWrapping = TextWrapping.Wrap,
                    FontFamily = new FontFamily("Consolas"),
                    Padding = new Thickness(24, 4, 0, 0),
                    BorderThickness = new Thickness(0, 0, 0, 0),
                    Foreground = Brushes.Gray,
                    Text = GetPlaceholder(txt)
                };

                var placeholderVisualBrush = new VisualBrush
                {
                    AlignmentX = AlignmentX.Left,
                    Stretch = Stretch.None,
                    AlignmentY = AlignmentY.Top,
                    Visual = placeholderTextBlock
                };

                txt.Background = placeholderVisualBrush;
                txt.TextChanged -= PlaceholderTextBox_TextChanged;
                txt.TextChanged += PlaceholderTextBox_TextChanged;
                TxtBrushes.Add(txt, placeholderVisualBrush);
            }
        }
        #endregion Events Handling
    }
}
